package com.renu.jdependencyanalyser.window.action;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;

import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.renu.jdependencyanalyser.cons.ProjectCons;
import com.renu.jdependencyanalyser.core.ClassBorderGene;
import com.renu.jdependencyanalyser.core.ProjectInfo;
import com.renu.jdependencyanalyser.data.ProjectDataCenter;
import com.renu.jdependencyanalyser.freemarker.DependencyProcessor;
import com.renu.jdependencyanalyser.model.ClassModel;
import com.renu.jdependencyanalyser.model.MethodModel;
import com.renu.jdependencyanalyser.utils.MyFileUtil;
import com.renu.jdependencyanalyser.utils.MyProjectUtil;
import com.renu.jdependencyanalyser.visualizer.GraphvizVisualizer;
import com.renu.jdependencyanalyser.utils.ImageDialogUtil;

import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MthdBorderAction extends AnAction  {

    ProjectInfo projectInfo = ProjectDataCenter.projectInfo;

    GraphvizVisualizer graphvizVisualizer = new GraphvizVisualizer();

    ClassBorderGene classBorderGene = null;

    MethodModel methodModel = null;

    ClassModel  classModel = null;

    @Override
    public void actionPerformed(AnActionEvent e) {
        // 获取光标位置的 PsiElement
        PsiElement psiElement = e.getData(CommonDataKeys.PSI_ELEMENT);
        VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE);
        file:///Users/renu/Documents/high/paper/ProjectTest/src/main/java/org/example/soot
        if (psiElement == null){
            return;
        }
            // 判断是否在方法名上
        if (!isOnMethodName(psiElement)) {
            // 在方法名上执行你的动作
            return;
        }

        byte[] bytes = psiElement.getText().getBytes();
        MyFileUtil.createOutDir(MyProjectUtil.projectBasePath + ProjectCons.OUT_INVOKE_DIR);



        //org.example.test.test.MyClass::
        //void testindir2(MyClass3, String)
        try(BufferedReader reader  = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes)))){
            String line = reader.readLine();
            //String regex = "\\w+\\s+\\w+\\([^)]*\\)";
            String regex = "(\\w+)\\s+(\\w+)\\((.*?)\\)";
            // 编译正则表达式
            Pattern pattern = Pattern.compile(regex);

            // 创建 Matcher 对象
            Matcher matcher = pattern.matcher(line);

            // 进行匹配
            if (matcher.find()) {
                // 提取匹配的部分
               String  returnType = matcher.group(1);
               String  methodName = matcher.group(2);
               String  parameters = extactPrmtsToTypes(matcher.group(3));
               String classSig = MyFileUtil.extractClassSigFromJavaPath(file.getPath());
               String methodSig  = MyFileUtil.convert2MthdSig(classSig,returnType,methodName,parameters);

               String filePath  = MyProjectUtil.projectBasePath + ProjectCons.OUT_INVOKE_DIR+ File.separator + methodName +".png";
               classModel = projectInfo.getClassModel(classSig);
               methodModel = projectInfo.getMethod(methodSig);
               classBorderGene = new ClassBorderGene(projectInfo,classModel);
               graphvizVisualizer.generateGraph(new DependencyProcessor(projectInfo,methodModel,classBorderGene.getDirOrIndirOuterMethodSig()),
                        filePath);
                ImageDialogUtil.showImage(filePath,"查看"+methodName+"关于第三方库的依赖图");


            } else {
                System.err.println("String does not match the pattern.");
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }catch (NullPointerException ex){
            System.err.println("projectInfo doesn't init");
        }





    }

    /**
     *
     * @param parameters MyClass3 myClass3,String s
     * @return (MyClass3, String)
     */
    private String extactPrmtsToTypes(String parameters) {
        StringBuilder sb = new StringBuilder();
        sb.append("(");
        String[] split = parameters.split(",");
        for (int i = 0; i < split.length; i++) {
            if (i > 0){
                sb.append(", ");
            }
            String type = split[i].split("\\s+")[0];
            sb.append(type);

        }
       sb.append(")");
        return sb.toString();


    }

    private boolean isOnMethodName(PsiElement psiElement) {
        // 在这里添加判断逻辑，例如判断是否在方法名上
        // 这里的示例判断是在 Java 文件中的方法名上
        return psiElement.getNode().getElementType().toString().equals("METHOD");

    }
}
